package com.apes.scm.voucher.service.ict;

import com.apes.framework.api.SpringManager;
import com.apes.scm.account.account.model.AccountingMethod;
import com.apes.scm.account.account.model.InventoryBatch;
import com.apes.scm.account.account.model.InventoryMode;
import com.apes.scm.account.account.service.InventoryService;
import com.apes.scm.account.method.Batch;
import com.apes.scm.account.method.BatchMethod;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.model.DeptEnum;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.voucher.model.Voucher;
import com.apes.scm.voucher.model.VoucherItem;
import com.apes.scm.voucher.service.BusinessType;
import com.apes.scm.voucher.service.ValuationService;
import com.apes.scm.voucher.service.VoucherService;
import com.apes.scm.voucher.service.VoucherType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static java.lang.Math.abs;
import static java.util.stream.Collectors.groupingBy;

/**
 * 功能：销售退回公司间交易
 *
 * @author xul
 * @create 2018-10-18 9:26
 */
@Component
public class SaleReturnIct extends AbstractIct {

    @Autowired
    InventoryService inventoryService;

    @Autowired
    ValuationService valuationService;

    public SaleReturnIct() {
        this.BusinessTypes = new String[]{BusinessType.SALE_RETURN};
    }


    /**
     * 公司间/跨公司交易：Inter-company/Cross-Company transactions
     *
     * @param voucher
     */
    @Override
    public void transaction(Voucher voucher) {
        voucher.getVoucherItems().stream()
                .filter(voucherItem -> voucherItem.cross()) //跨公司交易
                .collect(groupingBy(VoucherItem::obtainOwner))
                .forEach((owner, vis) -> {
                    PartyRole company = getCompany(voucher.getCompany());
                    PartyRole customer = getCustomer(owner);
                    PartyRole supplier = getSupplier(owner);

                    Voucher cv = new Voucher();
                    cv.setCompany(company);//公司
                    cv.setPartner(customer);//合作伙伴
                    cv.setScene(voucher.getScene());
                    cv.setOriginBusinessType(voucher.getOriginBusinessType());
                    cv.setOrigin(voucher.getOrigin());
                    cv.setSourceBusinessType(voucher.getInnerBusinessType());
                    cv.setSource(voucher.getInnerBusinessKey());
                    cv.setInvoiced(true);
                    cv.setReturned(true);
                    cv.setAccountingMethod(AccountingMethod.AM_PURCHASE);//核算方式
                    cv.setInventoryMode(InventoryMode.IM_OWN);//库存方式
                    cv.setVoucherType(VoucherType.CROSS_TRANSFER);//凭证类型
                    cv.setBusinessType(BusinessType.TRANSFER_ORDER);
                    cv.setCustomerExpand(voucher.getCustomerExpand());

                    Set<VoucherItem> voucherItems = new HashSet<>();
                    vis.stream().forEach(vItem -> new BatchMethod<Batch>() {
                        @Override
                        public Iterable<Batch> wrap() {
                            Dept dept = voucher.getDept();
                            if (dept == null) {
                                throw new RuntimeException("业务凭证销售部门为空！");
                            }
                            if (!(dept.existDeptType(DeptEnum.RETAIL) || dept.existDeptType(DeptEnum.SALE))) {
                                throw new RuntimeException("业务凭证部门为非销售部门！");
                            }
                            if (!dept.existDeptType(DeptEnum.PURCHASE)) {
                                throw new RuntimeException("业务凭证部门为非采购部门！");
                            }
                            List<InventoryBatch> inventories = inventoryService.findInventoryBatchForSaleOrder(company, dept, supplier, vItem.getProduct());
                            return inventoryService.wrapBatch(inventories, vItem.getUom(), inventory -> inventory.getBalanceQty() - inventory.getFrostQty());
                        }

                        @Override
                        public void succeed(Batch batch, double increment) {
                            VoucherItem vi = new VoucherItem();
                            vi.setProduct(vItem.getProduct());
                            vi.setUom(vItem.getUom());
                            InventoryBatch inventoryBatch = (InventoryBatch) batch.getEntity();
                            vi.setInventoryBatch(inventoryBatch);
                            vi.setSupplier(inventoryBatch.getSupplier());//供应商
                            double price = inventoryBatch.getUom().computePrice(inventoryBatch.getTaxCostPrice(), vItem.getUom());
                            vi.setPriceUnit(price);
                            vi.setProductQty(increment);
                            vi.setOriginItemId(vItem.getOriginItemId());
                            vi.setSourceItemId(String.valueOf(vItem.getId()));
                            vi.setVoucher(cv);
                            voucherItems.add(vi);

                            /**冻结批次**/
                            inventoryService.changeFrostQty(inventoryBatch, vItem.getUom(), abs(increment), company,
                                    voucher.getInnerBusinessType(), voucher.getId(), String.valueOf(vItem.getId()), "跨公司销售冻结批次");
                        }

                        @Override
                        public void error(double surplus) {
                            throw new RuntimeException("商品：["+vItem.getProduct().getId()+"]" + vItem.getProduct().getName() + " 价值库存数量少 " + surplus + vItem.getUom().getName() + "！");
                        }
                    }.execute(abs(vItem.getProductQty())));
                    cv.setVoucherItems(voucherItems);
                    SpringManager.getBean(VoucherService.class).save(cv);
                });
    }
}
